!** Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
!** See https://llvm.org/LICENSE.txt for license information.
!** SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

!* Tests for runtime library MATMUL routines

program p
  use check_mod
  integer, parameter :: NbrTests = 192
  integer, parameter :: n_extent = 10
  integer, parameter :: m_extent = 10
  integer, parameter :: k_extent = 10

  real*16, dimension(n_extent, m_extent) :: arr1
  real*16, dimension(n_extent, k_extent) :: arr2
  real*16, dimension(m_extent, k_extent) :: arr3

  REAL*16 :: expect(NbrTests)
  REAL*16 :: results(NbrTests)

  integer :: i,j
  do i = 1, 10
     do j = 1, 10
        arr1(i, j) = (10 * i + j - i) * 1.0_16
        arr2(i, j) = (10 * i + j - i) * 1.0_16
     end do
  end do

  data expect  /&
 32185.0_16,32690.0_16,33195.0_16,33700.0_16,34205.0_16,34710.0_16,35215.0_16,35720.0_16, &
 36225.0_16,36730.0_16,32690.0_16,33205.0_16,33720.0_16,34235.0_16,34750.0_16,35265.0_16, &
 35780.0_16,36295.0_16,36810.0_16,37325.0_16,33195.0_16,33720.0_16,34245.0_16,34770.0_16, &
 35295.0_16,35820.0_16,36345.0_16,36870.0_16,37395.0_16,37920.0_16,33700.0_16,34235.0_16, &
 32085.0_16,32580.0_16,33075.0_16,33570.0_16,34065.0_16,34560.0_16,35055.0_16,35550.0_16, &
 36045.0_16,36540.0_16,32580.0_16,33084.0_16,33588.0_16,34092.0_16,34596.0_16,35100.0_16, &
 35604.0_16,36108.0_16,36612.0_16,37116.0_16,33075.0_16,33588.0_16,34101.0_16,34614.0_16, &
 35127.0_16,35640.0_16,36153.0_16,36666.0_16,37179.0_16,37692.0_16,33570.0_16,34092.0_16, &
 23904.0_16,24318.0_16,24732.0_16,25146.0_16,25560.0_16,25974.0_16,26388.0_16,26802.0_16, &
 27216.0_16,27630.0_16,24318.0_16,24741.0_16,25164.0_16,25587.0_16,26010.0_16,26433.0_16, &
 26856.0_16,27279.0_16,27702.0_16,28125.0_16,24732.0_16,25164.0_16,25596.0_16,26028.0_16, &
 26460.0_16,26892.0_16,27324.0_16,27756.0_16,28188.0_16,28620.0_16,25146.0_16,25587.0_16, &
     0.0_16,32690.0_16,33195.0_16,33700.0_16,34205.0_16,34710.0_16,35215.0_16,35720.0_16, &
 36225.0_16,36730.0_16,    0.0_16,33205.0_16,33720.0_16,34235.0_16,34750.0_16,35265.0_16, &
 35780.0_16,36295.0_16,36810.0_16,37325.0_16,    0.0_16,33720.0_16,34245.0_16,34770.0_16, &
 35295.0_16,35820.0_16,36345.0_16,36870.0_16,37395.0_16,37920.0_16,    0.0_16,34235.0_16, &
 13820.0_16,14050.0_16,14280.0_16,14510.0_16,14740.0_16,14970.0_16,15200.0_16,15430.0_16, &
 15660.0_16,15890.0_16,14050.0_16,14285.0_16,14520.0_16,14755.0_16,14990.0_16,15225.0_16, &
 15460.0_16,15695.0_16,15930.0_16,16165.0_16,14280.0_16,14520.0_16,14760.0_16,15000.0_16, &
 15240.0_16,15480.0_16,15720.0_16,15960.0_16,16200.0_16,16440.0_16,14510.0_16,14755.0_16, &
     0.0_16,32690.0_16,    0.0_16,33700.0_16,    0.0_16,34710.0_16,    0.0_16,35720.0_16, &
     0.0_16,36730.0_16,    0.0_16,33205.0_16,    0.0_16,34235.0_16,    0.0_16,35265.0_16, &
     0.0_16,36295.0_16,    0.0_16,37325.0_16,    0.0_16,33720.0_16,    0.0_16,34770.0_16, &
     0.0_16,35820.0_16,    0.0_16,36870.0_16,    0.0_16,37920.0_16,    0.0_16,34235.0_16/

  arr3 = 0.0_16
  arr3 = matmul(transpose(arr1), arr2)
  call assign_result(1, 32, arr3, results)

  arr3 = 0.0_16
  arr3 = matmul(transpose(arr1(2:n_extent, :)), arr2(2:n_extent, :))
  call assign_result(33, 64, arr3, results)

  arr3 = 0.0_16
  arr3 = matmul(transpose(arr1(1:n_extent-1, :)),arr2(1:n_extent-1, :))
  call assign_result(65, 96, arr3, results)

  arr3 = 0.0_16
  arr3(2:m_extent, :) = matmul(transpose(arr1(:, 2:m_extent)), arr2)
  call assign_result(97, 128, arr3, results)

  arr3 = 0.0_16
  arr3 = matmul(transpose(arr1(1:n_extent-1:2, :)), arr2(1:n_extent-1:2, :))
  call assign_result(129, 160, arr3, results)

  arr3 = 0.0_16
  arr3(2:m_extent:2, :) = matmul(transpose(arr1(:, 2:m_extent:2)), arr2)
  call assign_result(161, 192, arr3, results)

  call checkr16(results, expect, NbrTests)

end program

subroutine assign_result(s_idx, e_idx , arr, rslt)
  integer:: s_idx, e_idx
  REAL*16, dimension(1:e_idx-s_idx+1) :: arr
  REAL*16, dimension(e_idx) :: rslt


  rslt(s_idx:e_idx) = arr

end subroutine

